/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.component.gateway.core.sign.info;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import info.peigen.hotpot.common.core.enums.Symbol;
import info.peigen.hotpot.component.gateway.core.sign.enums.SignType;
import lombok.*;
import lombok.experimental.FieldDefaults;
import lombok.experimental.SuperBuilder;
import org.w3c.dom.Document;

import java.util.Map;
import java.util.stream.Collectors;

/**
 * <b>(SignInfo)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2019-05-28
 */
@SuperBuilder
@Getter
@Setter
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class SignInfo {
    /** 待签名串，默认初始化 */
    @Builder.Default
    Map<String, String> parameters = Maps.newHashMap();
    /** 如果是xml则放到这里 */
    Document doc;
    /** 生成加密后文件的临时路径 */
    String   tmpDir;
    /** 待加密字符串 */
    String   encryptStr;
    /** 私钥 */
    String   privateKey;
    /** 公钥 */
    String   publicKey;
    /** 密码 */
    String   password;
    /** 签名串是否大写，默认小写 */
    @Builder.Default
    boolean             toUpperCase = false;
    /** 加签类型，默认MD5 */
    @Builder.Default
    SignType            signType    = SignType.MD5;
    /** 编码，默认UTF-8 */
    @Builder.Default
    String              charSet     = "UTF-8";
    /** 签名前是否根据ascii码排序 */
    @Builder.Default
    boolean             asciiSort   = true;
    /** 连接符，默认[&] */
    @Builder.Default
    Symbol              symbol      = Symbol.AMPERSAND;
    /** 其他参数 */
    @Builder.Default
    Map<String, String> others      = Maps.newHashMap();

    /**
     * 生成待签名字符串
     *
     * @return String
     */
    public String genSignature() {
        return parameters
                .entrySet()
                .stream()
                .filter(entry -> !StrUtil.isEmpty(entry.getValue()))
                .sorted(Map.Entry.comparingByKey())
                .map(entry -> entry.getKey() + Symbol.EQUALS.code() + entry.getValue())
                .collect(Collectors.joining(symbol.code()));
    }
}